<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>Three.js Materials</title>
    
    <style type="text/css">
      html { overflow: hidden; }
      body { margin: 0; padding: 0; overflow: hidden; font-family: Monospace; font-size: 13px; line-height: 20px; color: #333; }

      a { color: #0088cc; text-decoration: none; }
      a:hover, a:focus { color: #005580; text-decoration: underline; }

      /* stats */
      #fps, #ms { background: transparent !important; }
      #fpsText, #msText { color: #aaa !important; }
      #fpsGraph, #msGraph { display: none; }
    </style>

  </head>

  <body>

    <div id="container"></div>
    
    <script src="three/three.min.js"></script>
    <script src="three/OrbitControls.js"></script>
    <script src="three/Detector.js"></script>
    <script src="three/libs/stats.min.js"></script>
    <script src="three/libs/dat.gui.min.js"></script>
    <script src="three/libs/tween.min.js"></script>

    <script>

      if ( ! Detector.webgl ) Detector.addGetWebGLMessage();


      var container;

      var stats;

      var camera, controls, scene, renderer;

      var mesh1, mesh2, mesh3, mesh4, mesh5, mesh6, geometry, vnh;

      var helper;

      var mouseX = 0, mouseY = 0;

      var clock = new THREE.Clock();

      var windowHalfX = window.innerWidth / 2;
      var windowHalfY = window.innerHeight / 2;

      init();
      animate();

      function init() {
        scene = new THREE.Scene();

        container = document.getElementById( 'container' );

        camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 100000 );
        // camera = new THREE.OrthographicCamera( -windowHalfX, windowHalfX, windowHalfY, -windowHalfY, - 500, 1000 );
        camera.position.y = 50;
        camera.position.z = 400;
        camera.lookAt( scene.position );

        // add objects here


        // var helper = new THREE.GridHelper( 100, 20 );
        // helper.position.y = -100;
        // scene.add( helper );

        var ambLight = new THREE.AmbientLight( 0x444444 );
        scene.add( ambLight );

        var light = new THREE.DirectionalLight( 0xdddddd, 1 );
        light.position.set( -100, 100, 100 );
        scene.add( light );
        
        // var lightHelper = new THREE.DirectionalLightHelper( light, 20 );
        // scene.add( lightHelper );

        // materials
        var materialBasic = new THREE.MeshBasicMaterial({ color: 0xaaaaaa });
        var materialLambert = new THREE.MeshLambertMaterial({ color: 0xaaaaaa });
        var materialPhong = new THREE.MeshPhongMaterial({ color: 0xaaaaaa, shininess: 40 });
        var materialStandard = new THREE.MeshStandardMaterial({ color: 0xaaaaaa, roughness: 0.6 });
        var materialToon = new THREE.MeshToonMaterial({ color: 0xaaaaaa, shininess: 1 });
        var materialNormal = new THREE.MeshNormalMaterial();

        var size = 50;
        var num = 4;

        geometry = new THREE.SphereGeometry( size, 24, 16 );
        // , 0, Math.PI * 2, Math.PI / 4, Math.PI / 2

        // geometry.mergeVertices();
        // geometry.computeFaceNormals();
        // geometry.computeVertexNormals();

        mesh1 = new THREE.Mesh( geometry, materialBasic );
        mesh1.position.x = -300;
        scene.add( mesh1 );

        mesh2 = new THREE.Mesh( geometry.clone(), materialLambert );
        mesh2.position.x = -180;
        scene.add( mesh2 );

        mesh3 = new THREE.Mesh( geometry.clone(), materialPhong );
        mesh3.position.x = -60;
        scene.add( mesh3 );

        mesh4 = new THREE.Mesh( geometry.clone(), materialStandard );
        mesh4.position.x = 60;
        scene.add( mesh4 );

        mesh5 = new THREE.Mesh( geometry.clone(), materialToon );
        mesh5.position.x = 180;
        scene.add( mesh5 );

        mesh6 = new THREE.Mesh( geometry.clone(), materialNormal );
        mesh6.position.x = 300;
        scene.add( mesh6 );

        vnh = new THREE.VertexNormalsHelper( mesh6, 15, 0x333333 );
        vnh.visible = false;
        scene.add(vnh);


        // helper = new THREE.VertexNormalsHelper( mesh2, 15, 0x0000ff );
        // scene.add( helper );

        // var wireframe = new THREE.WireframeHelper( mesh2, 0x000000 );
        // scene.add( wireframe );

        // helper = new THREE.FaceNormalsHelper( mesh3, 15, 0xff0000 );
        // scene.add( helper );

        // var wireframe = new THREE.WireframeHelper( mesh3, 0x000000 );
        // scene.add( wireframe );

        // setupTween();


        renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true } );
        // renderer.setClearColor( 0xBBBBBB, 1 );
        renderer.setClearColor( 0x000000, 0 ); // the default
        renderer.setSize( window.innerWidth, window.innerHeight );

        container.appendChild( renderer.domElement );


        controls = new THREE.OrbitControls( camera, renderer.domElement );
        controls.enableKeys = false;

        stats = new Stats();
        stats.domElement.style.position = 'absolute';
        stats.domElement.style.top = '0px';
        container.appendChild( stats.domElement );

        //

        window.addEventListener( 'resize', onWindowResize, false );

      }


      function setupGui() {
        // dat.GUI debugging -----------------------------------------
        var gui = new dat.GUI();
        var f1 = gui.addFolder('meshOuter rotation');
        f1.add(mesh.position, 'x', 0, 2*Math.PI);
        f1.add(mesh.position, 'y', 0, 2*Math.PI);
        f1.add(mesh.position, 'z', 0, 2*Math.PI);
        f1.open();
      }


      function onWindowResize() {

        windowHalfX = window.innerWidth / 2;
        windowHalfY = window.innerHeight / 2;

        // Perspective
        camera.aspect = window.innerWidth / window.innerHeight;

        // Orthographic
        // camera.left = -windowHalfX;
        // camera.right = windowHalfX;
        // camera.top = windowHalfY;
        // camera.bottom = -windowHalfY;

        camera.updateProjectionMatrix();

        renderer.setSize( window.innerWidth, window.innerHeight );  
      }

      //


      function animate() {
        requestAnimationFrame( animate );
        render();
        stats.update();
        // controls.update();
        TWEEN.update();
      }

      function render() {
        // var delta = clock.getDelta();
        // mesh4.rotation.y -= 0.2 * delta;
        vnh.update();

        renderer.render( scene, camera );
      }


      // --------

      function setupTween(obj, prop, targetValue) {
        var update  = function(){
          obj[prop] = current.property;
        }
        
        var current = { property: obj[prop] };
        var target = { property: targetValue };

        var tween = new TWEEN.Tween(current).to(target, 800)
          .easing(TWEEN.Easing.Cubic.Out)
          .onUpdate(update);

        tween.start();
      }

      var step = 1;

      function applyStep(step) {
        // console.log(step);
        
        if   (step == 1) {
          setupTween( camera.position, 'x', 0 ); // default
          setupTween( mesh1.position, 'y', 0 );
        }
        else if (step == 2) {
          setupTween( camera.position, 'x', mesh1.position.x );
          setupTween( mesh1.position, 'y', 20 );
          setupTween( mesh2.position, 'y', 0 );
        }
        else if (step == 3) {
          setupTween( camera.position, 'x', mesh2.position.x );
          setupTween( mesh1.position, 'y', 0 );
          setupTween( mesh2.position, 'y', 20 );
          setupTween( mesh3.position, 'y', 0 );
        }
        else if (step == 4) {
          setupTween( camera.position, 'x', mesh3.position.x );
          setupTween( mesh2.position, 'y', 0 );
          setupTween( mesh3.position, 'y', 20 );
          setupTween( mesh4.position, 'y', 0 );
        }
        else if (step == 5) {
          setupTween( camera.position, 'x', mesh4.position.x );
          setupTween( mesh2.position, 'y', 0 );
          setupTween( mesh3.position, 'y', 0 );
          setupTween( mesh4.position, 'y', 20 );
          setupTween( mesh5.position, 'y', 0 );
        }
        else if (step == 6) {
          setupTween( camera.position, 'x', mesh5.position.x );
          setupTween( mesh2.position, 'y', 0 );
          setupTween( mesh3.position, 'y', 0 );
          setupTween( mesh4.position, 'y', 0 );
          setupTween( mesh5.position, 'y', 20 );
          setupTween( mesh6.position, 'y', 0 );
        }
        else if (step == 7) {
          setupTween( camera.position, 'x', mesh6.position.x );
          setupTween( mesh5.position, 'y', 0 );
          setupTween( mesh6.position, 'y', 20 );
          
          vnh.visible = false;
        }
        else if (step == 8) {
          vnh.visible = true;
        }
      }

      onmessage = function(e) {
        // paused = (e.data == 'pause' || e.data == 'slide:stop');
        step = e.data.director.args[0];
        applyStep( step );
      };

      function forward() {
        step++;
        if (step > 8) { step = 8; return; }
        applyStep(step);
      }

      function back() {
        step--;
        if (step <= 0) { step = 1; return; }
        applyStep(step);
      }

      // Controls for stand-alone
      window.addEventListener('keydown', function (e) {
        if (e.keyCode == 38 || e.keyCode == 37) back();
        if (e.keyCode == 40 || e.keyCode == 39) forward();
      });

    </script>

  </body>
</html>
